package com.sky.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sky.entity.Orders;
import com.sky.entity.User;
import com.sky.mapper.OrdersMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkspaceService;
import com.sky.view.BusinessDataVO;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private WorkspaceService workspaceService;

    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private UserMapper userMapper;

    //导出运营数据报表
    @Override
    public void export(HttpServletResponse httpServletResponse) throws IOException {
        //获取数据
        LocalDate endDate = LocalDate.now().minusDays(1);
        LocalDate beginDate = LocalDate.now().minusDays(30);
        BusinessDataVO businessData = workspaceService.getBusinessData(beginDate, endDate);
        //操作excel填充数据
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        XSSFWorkbook xssfWorkbook = new XSSFWorkbook(inputStream);
        //写入时间
        XSSFSheet xssfSheet = xssfWorkbook.getSheet("sheet1");
        xssfSheet.getRow(1).getCell(1).setCellValue("时间: ["+beginDate+"] 至 ["+endDate+"]");
        //概览数据
        XSSFRow row1 = xssfSheet.getRow(3);
        row1.getCell(2).setCellValue(businessData.getTurnover());
        row1.getCell(4).setCellValue(businessData.getOrderCompletionRate());
        row1.getCell(6).setCellValue(businessData.getNewUsers());
        XSSFRow row2 = xssfSheet.getRow(4);
        row2.getCell(2).setCellValue(businessData.getValidOrderCount());
        row2.getCell(4).setCellValue(businessData.getUnitPrice());
        //详细数据
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<Orders>()
                .between(Orders::getOrderTime,
                        LocalDateTime.of(beginDate, LocalTime.MIN),
                        LocalDateTime.of(endDate, LocalTime.MAX));
        List<Orders> ordersList = ordersMapper.selectList(queryWrapper);
        if(ordersList.isEmpty()) return;
        Map<LocalDate, BusinessDataVO> collect = ordersList.stream()
                .collect(Collectors.groupingBy(o -> o.getOrderTime().toLocalDate(),
//                        LinkedHashMap::new,
                        Collectors.collectingAndThen(
                                Collectors.toList(),
                                (List<Orders> orders) -> {
                                    if(!orders.isEmpty()){
                                        if(orders.stream().anyMatch(o -> o.getStatus().equals(Orders.COMPLETED))){
                                            //日营业额
                                            Double turnover = orders.stream()
                                                    .filter(o -> o.getStatus().equals(Orders.COMPLETED))
                                                    .map(Orders::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add)
                                                    .doubleValue();
                                            //日有效订单数
                                            Integer validOrderCount = (int) orders.stream()
                                                    .filter(o -> o.getStatus().equals(Orders.COMPLETED))
                                                    .count();
                                            //日订单完成率
                                            Double completionRate = BigDecimal.valueOf(validOrderCount)
                                                    .divide(BigDecimal.valueOf(orders.size()), 4, RoundingMode.HALF_UP)
                                                    .doubleValue();
                                            //日平均客单价
                                            Double unitPrice = BigDecimal.valueOf(turnover)
                                                    .divide(BigDecimal.valueOf(validOrderCount), 4, RoundingMode.HALF_UP)
                                                    .doubleValue();
                                            return new BusinessDataVO(turnover, validOrderCount, completionRate, unitPrice, 0);
                                        }else {
                                            return new BusinessDataVO((double) 0,0,(double) 0,(double) 0,0);
                                        }
                                    }else {
                                        return new BusinessDataVO((double) 0,0,(double) 0,(double) 0,0);
                                    }
                                }
                        )));
        for (LocalDate date=beginDate;date.isBefore(endDate.plusDays(1));date=date.plusDays(1)){
            collect.putIfAbsent(date,new BusinessDataVO((double) 0,0,(double) 0,(double) 0,0));
        }
        //日新增用户
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<User>()
                .between(User::getCreateTime,
                        LocalDateTime.of(beginDate, LocalTime.MIN),
                        LocalDateTime.of(endDate, LocalTime.MAX));
        List<User> users = userMapper.selectList(userLambdaQueryWrapper);
        Map<LocalDate, Long> newUser = users.stream()
                .collect(Collectors.groupingBy(u -> u.getCreateTime().toLocalDate(),
//                        LinkedHashMap::new,
                        Collectors.counting()));
        for (LocalDate date=beginDate;date.isBefore(endDate.plusDays(1));date=date.plusDays(1)){
            newUser.putIfAbsent(date,0L);
        }
        //写入表格
        ArrayList<LocalDate> dates = new ArrayList<>(collect.keySet());
        Collections.sort(dates);
        int i=0;
        for (LocalDate date : dates) {
            XSSFRow xssfRow = xssfSheet.getRow(i + 7);
            xssfRow.getCell(1).setCellValue(date.toString());
            xssfRow.getCell(2).setCellValue(collect.get(date).getTurnover());
            xssfRow.getCell(3).setCellValue(collect.get(date).getValidOrderCount());
            xssfRow.getCell(4).setCellValue(collect.get(date).getOrderCompletionRate());
            xssfRow.getCell(5).setCellValue(collect.get(date).getUnitPrice());
            xssfRow.getCell(6).setCellValue(newUser.get(date));
            i++;
        }
        //通过输出流下载到客户端浏览器
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        xssfWorkbook.write(outputStream);
        //关闭资源
        outputStream.close();
        inputStream.close();
        xssfWorkbook.close();
    }

}
